package org.linlinjava.litemall.wx.service;

import org.linlinjava.litemall.wx.dto.CaptchaItem;
import org.linlinjava.litemall.wx.dto.IPInfo;

import java.time.LocalDateTime;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 缓存系统中的验证码
 */
public class CaptchaCodeManager {
    private static Integer MAX_LIMIT = 10;
    private static ConcurrentHashMap<String, CaptchaItem> captchaCodeCache = new ConcurrentHashMap<>();

    private static ConcurrentHashMap<String, IPInfo> ipAddressCache = new ConcurrentHashMap<>();

    /**
     * 添加到缓存
     *
     * @param phoneNumber 电话号码
     * @param code        验证码
     */
    public static boolean addToCache(String phoneNumber, String code) {

        //已经发过验证码
        CaptchaItem savedCap = captchaCodeCache.get(phoneNumber);
        if (savedCap != null) {
            //还在锁定期内
            if (savedCap.getLockTime().isAfter(LocalDateTime.now())) {
                return false;
            }
        }
        CaptchaItem captchaItem = new CaptchaItem();
        captchaItem.setPhoneNumber(phoneNumber);
        captchaItem.setCode(code);
        // 有效期为5分钟
        captchaItem.setExpireTime(LocalDateTime.now().plusMinutes(5));
        //锁定期为1分钟
        captchaItem.setLockTime(LocalDateTime.now().plusMinutes(1));
        captchaCodeCache.put(phoneNumber, captchaItem);
        return true;
    }

    public static void addToCacheForce(String phoneNumber, String code) {
        CaptchaItem item = captchaCodeCache.get(phoneNumber);
        if (item == null) {
           addToCache(phoneNumber, code);
        }
        else {
            item.setCode(code);
            captchaCodeCache.put(phoneNumber, item);
        }
    }

    public static void setNullCode(String phoneNum) {
        CaptchaItem item = captchaCodeCache.get(phoneNum);
        if (item != null) {
            addToCacheForce(phoneNum,null);
        }
    }

    public static void setNullCode(String... phoneNums) {
        for (String phone : phoneNums) {
            setNullCode(phone);
        }
    }

    /**
     * 新增缓存的IP地址
     **/
    public static boolean addIpAddress(String ipAddress) {
        IPInfo ipInfo = ipAddressCache.get(ipAddress);
        if (ipInfo != null) {
            if (ipInfo.getExpireTime().isAfter(LocalDateTime.now())) {
                Integer times = ipInfo.getTimes();
                if (times > MAX_LIMIT) {
                    return false;
                } else {
                    ipInfo.setTimes(++times);
                }
            } else {
                //存在但是已过期，重置次数
                ipInfo.setTimes(1);
            }
        } else {
            ipInfo = new IPInfo();
            ipInfo.setTimes(1);
            ipInfo.setIpAddress(ipAddress);
        }
        ipInfo.setExpireTime(LocalDateTime.now().plusMinutes(20));
        ipAddressCache.put(ipAddress, ipInfo);
        return true;
    }

    /**
     * 获取缓存的验证码
     *
     * @param phoneNumber 关联的电话号码
     * @return 验证码
     */
    public static String getCachedCaptcha(String phoneNumber) {
        //没有这个电话记录
        if (captchaCodeCache.get(phoneNumber) == null) {
            return null;
        }

        //有电话记录但是已经过期
        if (captchaCodeCache.get(phoneNumber).getExpireTime().isBefore(LocalDateTime.now())) {
            captchaCodeCache.remove(phoneNumber);
            return null;
        }

        return captchaCodeCache.get(phoneNumber).getCode();
    }

    /**
     * 获取缓存的IP地址
     **/
    public static boolean ipAddressIsLegal(String ipAddress) {
        IPInfo ipInfo = ipAddressCache.get(ipAddress);

        //没有这个ip记录
        if (ipInfo == null) {
            return true;
        }

        else {
            if (ipInfo.getExpireTime().isBefore(LocalDateTime.now())) {
                ipAddressCache.remove(ipAddress);
                return true;
            }
            else {
                return ipInfo.getTimes() < MAX_LIMIT;
            }
        }
    }

    public static boolean ipAddressNotLegal(String ipAddress) {
        return !ipAddressIsLegal(ipAddress);
    }
}
